package redis.task;

import com.fasterxml.jackson.annotation.JsonTypeInfo;

public class DeferredResultTaskResult<T> {
    enum ResultState {
        success,    // 执行成功
        failed,     // 执行失败
        offline,    // 设备离线
        timeout,    // 任务超时
        notSupport, // 不支持的任务
    }

    private long taskId;        // 任务流水号
    private String serverId;    // 执行任务主机ID
    private String fromServerId; // 任务发起主机ID
    private ResultState result;
    @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
    private T data;
    private String message;

    public DeferredResultTaskResult() { }

    public DeferredResultTaskResult(DeferredResultTask task) {
        this.taskId = task.getTaskId();
        this.serverId = task.getServerId();
        this.fromServerId = task.getFromServerId();
        this.result = null;
        this.data = null;
    }

    public void copy(DeferredResultTaskResult<T> result) {
        this.taskId = result.taskId;
        this.serverId = result.getServerId();
        this.fromServerId = result.getFromServerId();
        this.result = result.result;
        this.data = result.data;
    }

    public static <T> DeferredResultTaskResult<T> succeed(DeferredResultTask task) {
        return resultOf(task, ResultState.success, null);
    }

    public static DeferredResultTaskResult succeed(DeferredResultTask task, Object data) {
        return resultOf(task, ResultState.success, data);
    }

    public static <T> DeferredResultTaskResult<T> failed(DeferredResultTask task) {
        return resultOf(task, ResultState.failed, null);
    }

    public static <T> DeferredResultTaskResult<T> failed(DeferredResultTask task, String message) {
        DeferredResultTaskResult<T> result = resultOf(task, ResultState.failed, null);
        result.setMessage(message);
        return result;
    }

    public static <T> DeferredResultTaskResult<T> offline(DeferredResultTask task) {
        return resultOf(task, ResultState.offline, null);
    }

    public static <T> DeferredResultTaskResult<T> timeout(DeferredResultTask task) {
        return resultOf(task, ResultState.timeout, null);
    }

    public static <T> DeferredResultTaskResult<T> notSupport(DeferredResultTask task) {
        return resultOf(task, ResultState.notSupport, null);
    }

    public static <T> DeferredResultTaskResult<T> resultOf(DeferredResultTask task, ResultState state, T data) {
        DeferredResultTaskResult<T> result = new DeferredResultTaskResult<>();
        result.taskId = task.getTaskId();
        result.serverId = task.getServerId();
        result.fromServerId = task.getFromServerId();
        result.result = state;
        result.data = data;
        return result;
    }

    public long getTaskId() {
        return taskId;
    }

    public void setTaskId(long taskId) {
        this.taskId = taskId;
    }

    public String getServerId() {
        return serverId;
    }

    public void setServerId(String serverId) {
        this.serverId = serverId;
    }

    public String getFromServerId() {
        return fromServerId;
    }

    public void setFromServerId(String fromServerId) {
        this.fromServerId = fromServerId;
    }

    public ResultState getResult() {
        return result;
    }

    public void setResult(ResultState result) {
        this.result = result;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
